<template>
  <div id="carousel">
    <div class="switch prev" v-show="showSwitch">
      <a href="javascript:;">上</a>
    </div>
    <div class="inner">
      <ul class="list">
        <li class="item" v-for="(it, k) in list" :key="k"><img :src="it" alt=""></li>
      </ul>
    </div>
    <div class="switch next" v-show="showSwitch">
      <a href="javascript:;">下</a>
    </div>
  </div>
</template>

<script>
/**
 * 2017-5-20 By Qing
 * @param { @carousel } opts 
 */
import { getdom, addEvt } from '../common';

export default {
  name: 'carousel',
  props: ['data', 'showSwitch'],
  data() {
    return {
      list: []
    }
  },
  created() {
    this.list = this.data;
  },
  mounted() {
    this.carousel({
      el: '#carousel'
    })
  },
  methods: {
    carousel(opts) {
      var baseCg = {
        el: 'body',
        autoPlay: true,  // 是否开启自动轮播
        duration: 3000,  // 自动轮播时间间隔
        indicator: true,  // 是否显示指示器
      };
      var opts = typeof opts === 'object' ? extend(baseCg,opts) : baseCg;
      var	containerH = getdom(opts.el).offsetWidth,
        innerH = (containerH >= window.innerWidth) ? window.innerWidth : containerH,  // 可视区高度
        inner = getdom(opts.el + ' .inner'),
        item = getdom(opts.el + ' .item'),
        itemL = item.length,
        prev = getdom(opts.el + ' .prev')[0],
        next = getdom(opts.el + ' .next')[0],
        // prevW = nextW = prev.offsetWidth,
        ul = getdom(opts.el + ' .list'),
        idt = null,
        autoplay = null,
    // 						up = getdom(opts.el + ' .narrow .up'),
    // 						dw = getdom(opts.el + ' .narrow .dw'),
        index = 0,
        totalOffset = innerH * index;
      /**
       * @des 初始化
       */
      function _init() {
        ul[0].style.left = totalOffset + 'px';
        inner[0].style.width = innerH + 'px';
        for(var i=0,l=item.length; i<l; i++) {
          item[i].style.width = innerH + 'px';
        }
        ul[0].style.width = (innerH * item.length) + 'px';
        
        dom(item);
        
        opts.indicator && indicator();
        
        new Swipe();
      }
      /**
       * @des 继承函数
       */
      function extend(son, child) {
        var child = typeof child === 'object' ? child : {};
        for(var k in child) {
          son[k] = child[k];
        }
        return son;
      }
      /**
       * 
       * @param {*} tagName 
       * @param {*} props 
       * @param {*} children 
       */
      function parseDom(str) {
        const doc = document.createElement('div');
        doc.innerHTML = str;
        console.log('66...........', doc.children[0]);
        return doc.children[0];
      }
      /**
       * @des DOM树构建函数
       */
      function Fragment(tagName, props, children) {
        this.tagName = tagName;
        this.props = props;
        this.children = children;
      }
      Fragment.prototype.render = function() {
        var fg = document.createDocumentFragment(),
          el = document.createElement(this.tagName),
          props = this.props,
          children = this.children || [],
          domParser = new DOMParser();
        for(var p in props) {
          el.setAttribute(p, props[p]);
        }
        children.forEach(function(child) {
          var childEl = (child instanceof Fragment)
          ? child.render()
          : parseDom(child);
          // : document.createTextNode(child)
          
          console.log('96.............', el, childEl);
          el.appendChild(childEl);
        })
        fg.appendChild(el);
        return fg;
      }
      function el(tagName, props, children) {
        return new Fragment(tagName, props, children);
      }
      /**
       * @des DOM树重构，以实现loop
       */
      function dom(ele) {
        var tagName = ele[0].nodeName.toLowerCase(),
          props1 = {},
          props2 = {},
          children1 = [],
          children2 = [],
          attrArr1 = [].slice.call(ele[0].attributes),
          attrArr2 = [].slice.call(ele[ele.length - 1].attributes);
        
        attrArr1.forEach(function(item, i) {
          item.nodeName == 'class'
            ? props1[item.nodeName] = item.nodeValue
            : props1[item.nodeName] = 'position: absolute; ' + item.nodeValue + ' left:'+ (innerH * itemL) +'px;';
        })
        attrArr2.forEach(function(item, i) {
          item.nodeName == 'class'
            ? props2[item.nodeName] = item.nodeValue
            : props2[item.nodeName] = 'position: absolute; ' + item.nodeValue + ' left:-'+ innerH +'px;';
        })
        children1.push(ele[0].innerHTML);
        children2.push(ele[ele.length - 1].innerHTML);
        
        var eleLast = el(tagName, props1, children1).render();
        ul[0].appendChild(eleLast);
        var eleFirst = el(tagName, props2, children2).render();
        ul[0].insertBefore(eleFirst, item[0]);
      }
      
      /**
       * @des 指示器
       */
      function indicator() {
        var idtArr = [];
        
        for(var i=0,l=item.length; i<l; i++) {
          idtArr.push(el('li', {class: 'idt-i'}, []));
        }
        var ul = el('ul', {class: 'indicator'}, idtArr);
        var ulRoot = ul.render();
        inner[0].appendChild(ulRoot)
        
        idt = getdom(`${opts.el} .indicator`)[0];
        idt.children[index].classList.add('active');
      }
      function idtActive() {
        for(var i=0,l=idt.children.length; i<l; i++) {
          idt.children[i].classList.remove('active');
        }
        if(index >= idt.children.length) {
          idt.children[0].classList.add('active');
        }else {
          idt.children[index].classList.add('active');
        }
        
      }
      /**
       * @des 滑动操作
       */
      function Swipe() {
        var startY, moveY, endY, me = this;
        document.addEventListener('touchstart', function(e) {
          startY = e.changedTouches[0].pageX;
        }, false);
        document.addEventListener('touchmove', function(e) {
          moveY = e.changedTouches[0].pageX;
          h(startY, moveY);
        }, false);
        document.addEventListener('touchend', function(e) {
          endY = e.changedTouches[0].pageX;
          (Math.abs(endY - startY) >= 100) && y(startY, endY)
        }, false);
        idt && idt.addEventListener('click', function(e) {
          var oldIndex = index, newIndex;
          newIndex = [].slice.call(idt.children).indexOf(e.target);
          if(newIndex >= oldIndex) {
            index = newIndex-1;
            me.swipeU();
          }else if(newIndex < oldIndex) {
            index = newIndex+1;
            me.swipeD();
          }
        }, false);
        prev.addEventListener('click', function(e) {
          me.swipeD();
        }, false);
        next.addEventListener('click', function(e) {
          me.swipeU();
        }, false);
        opts.autoPlay == 1 ? autoplay = setInterval(function() {
          me.swipeU();
        }, 3000) : autoplay = null;
        function h(s,m) {
          if(m - s > 0) {
            me.swipeDown(m-s);
          }else {
            me.swipeUp(m-s);
          }
        }
        function y(s,e) {
          if(e - s < 0) {
            me.swipeU()
          }else {
            me.swipeD();
          }
        }
      }
      Swipe.prototype = {
        swipeUp(m) {
          if(index >= item.length-1) return;
          totalOffset = -innerH * index + m;
          ul[0].style.left = totalOffset + 'px';
          
        },
        swipeDown(m) {
          if(index === 0) return;
          totalOffset = -innerH * index + m;
          ul[0].style.left = totalOffset + 'px';
        },
        swipeU() {
          if(index >= item.length) {
            // ul归位
            index = 0;
            totalOffset = -innerH * index;
            ul[0].style.left = totalOffset + 'px';
          };
          
          index++;
          idt && idtActive();

          var timer = setInterval(function() {
            if(innerH * index + totalOffset <= 1) {
              totalOffset = -innerH*index;
              ul[0].style.left = totalOffset + 'px';
              clearInterval(timer);
              return;
            }else {
              totalOffset += -(innerH*index + totalOffset)/10;
              ul[0].style.left = totalOffset + 'px';
            }
          }, 20);
        },
        swipeD() {
          if(index === 0) {
            // ul归位
            index = 3;
            totalOffset = -innerH * index;
            ul[0].style.left = totalOffset + 'px';
          };
          index--;
          idt && idtActive();

          var timer = setInterval(function() {
            if(-totalOffset - innerH * index <= 1) {
              totalOffset = -innerH * index;
              ul[0].style.left = totalOffset + 'px';
              clearInterval(timer);
              return;
            }else {
              totalOffset += -(innerH*index + totalOffset)/10;
              ul[0].style.left = totalOffset + 'px';
            }
          }, 20);
        }
      }
      _init();
    }
  }
}
</script>

<style lang="less" scoped>
#carousel {position: relative; width: 100%; height: auto;}
#carousel .inner {height: 100%; overflow: hidden;}
#carousel .inner .list {position: relative; height: auto;}
#carousel .item {width: 100%; float: left; font-size: 5em; color: #eee; line-height: auto; text-align: center; background-color: rgba(52,136,210,.7);}
@keyframes breath{
  0% {bottom: 38px;}
  25% {bottom: 26px;}
  50% {bottom: 38px;}
  75% {bottom: 50px;}
  100% {bottom: 38px;}
}
/* .inner .narrow {position: absolute; bottom: 38px; left: 50%; transform: translateX(-50%); width: 50px; height: 40px; animation: breath 2s linear infinite;} */
#carousel .switch {position: absolute; top: 50%; transform: translateY(-50%); width: 70px; overflow: hidden; z-index: 113;}
#carousel .switch.prev {left: 0; padding-right: 30px;}
#carousel .switch.next {right: 0; padding-left: 30px;}
/* #carousel .switch.prev a {background: url(../img/7.png) no-repeat center;} */
/* #carousel .switch.next a {background: url(../img/6.png) no-repeat center;} */
#carousel .switch.prev a, #carousel .switch.next a {display: block; height: 80px; background-color: rgba(0,0,0,.2); line-height: 80px; text-decoration: none; text-align: center; color: #fff;}
#carousel .switch.prev a:hover, #carousel .switch.next a:hover {background-color: rgba(0,0,0,.4);}

#carousel .indicator {position: absolute; bottom: 0; width: 100%; text-align: center; background-color: rgba(0,0,0,.3);}
#carousel .indicator .idt-i {display: inline-block; width: 12px; height: 12px; border-radius: 100%; margin: 15px 5px; vertical-align: middle; background-color: rgba(255,255,255,.5); font-size: 10px; color: #fff;}
#carousel .indicator .idt-i.active {background-color: rgba(0,0,0,.5);}
</style>